package persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Vector;

import clases.casillas.Casilla;
import clases.casillas.CasillaComodin;
import clases.casillas.CasillaNormal;

public class AdministradorCasilla {
	private static AdministradorCasilla instancia;

	private AdministradorCasilla() {

	}

	public static AdministradorCasilla getInstancia() {
		if (instancia == null)
			instancia = new AdministradorCasilla();

		return instancia;
	}

	public void insert(CasillaNormal cn) {
		try {
			Connection con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement s = con
					.prepareStatement("insert into casillas (tipoCasilla, nombre) VALUES ('normal', ?)");
			// agregar campos
			s.setString(1, cn.getNombre());
			s.execute();
			PoolConnection.getPoolConnection().realeaseConnection(con);
		} catch (Exception e) {
			System.out.println();
		}

	}


	public void insert(CasillaComodin cc) {
		try {
			Connection con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement s = con
					.prepareStatement("INSERT INTO casillas (tipoCasilla, nombre) VALUES ('comodin', ?)");
			// agregar campos
			s.setString(1, cc.getNombre());
			s.execute();

			// contar la cantidad de veces que se repite cada casilla
			Hashtable<Casilla, Integer> repeticionesCasilla = new Hashtable<Casilla, Integer>();
			for (Casilla casillaEnComodin : cc.getCasillas()) {
				if (!repeticionesCasilla.containsKey(casillaEnComodin))
					repeticionesCasilla.put(casillaEnComodin, 1);
				else
					repeticionesCasilla.put(casillaEnComodin,
							repeticionesCasilla.get(casillaEnComodin) + 1);

			}

			for (Casilla casilla : repeticionesCasilla.keySet()) {
				s = con.prepareStatement("INSERT INTO casillasEnComodin VALUES (?,?,?)");

				s.setString(1, cc.getNombre());
				s.setString(2, casilla.getNombre());
				s.setInt(3, repeticionesCasilla.get(casilla));

				s.execute();
			}

			/*
			 * @SuppressWarnings("unchecked") ArrayList<Casilla>
			 * casillasTempPrincipal = (ArrayList<Casilla>)
			 * cc.getCasillas().clone();
			 * 
			 * for (Casilla casillaTemp : casillasTempPrincipal) {
			 * 
			 * ArrayList<Casilla> casillasTemp = (ArrayList<Casilla>)
			 * cc.getCasillas().clone(); casillasTemp.remove(casillaTemp); int
			 * cont = 1;
			 * 
			 * for (Casilla casilla : casillasTemp) { if
			 * (casilla.getNombre().equals(casillaTemp.getNombre())){
			 * casillasTempPrincipal.remove(casilla); cont = (cont + 1); } }
			 * 
			 * s =
			 * con.prepareStatement("INSERT INTO casillasEnComodin VALUES (?,?,?)"
			 * ); //agregar campos s.setString(1, cc.getNombre());
			 * s.setString(2, casillaTemp.getNombre()); s.setInt(3, cont);
			 * s.execute(); }
			 */
			PoolConnection.getPoolConnection().realeaseConnection(con);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	public void updateNombre(Object o, String nuevoNombre) {
		try {
			CasillaNormal a = (CasillaNormal) o;
			Connection con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement s = con
					.prepareStatement("UPDATE casillas SET nombre = ? WHERE (nombre = ?)");
			// agregar campos
			s.setString(1, nuevoNombre);
			s.setString(2, a.getNombre());
			s.execute();
			PoolConnection.getPoolConnection().realeaseConnection(con);
		} catch (Exception e) {
			System.out.println();
		}

	}

	public void delete(CasillaNormal cn) {
		try {
			Connection con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement s = con
					.prepareStatement("delete from casillas where nombre = ?");
			s.setString(1, cn.getNombre());
			s.execute();
			PoolConnection.getPoolConnection().realeaseConnection(con);
		} catch (Exception e) {
			System.out.println();
		}
	}

	public void delete(CasillaComodin cc) {
		try {
			Connection con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement s = con
					.prepareStatement("DELETE FROM CasillasEnComodin WHERE nombre = ?");
			s.setString(1, cc.getNombre());
			s.execute();

			s = con.prepareStatement("DELETE FROM Casillas WHERE nombre = ?");
			s.setString(1, cc.getNombre());
			s.execute();

			PoolConnection.getPoolConnection().realeaseConnection(con);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

	}

	public Vector<Casilla> traerTodas() {
		Vector<Casilla> casillas = new Vector<Casilla>();
		Connection con = null;
		try {
			con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement s = con
					.prepareStatement("select nombre from casillas");
			ResultSet rs = s.executeQuery();
			while (rs.next()) {
				String nombre = rs.getString("nombre");
				casillas.add(traer(nombre));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (con != null)
				PoolConnection.getPoolConnection().realeaseConnection(con);
		}

		return casillas;
	}

	public Casilla traer(String nombreCasilla) {
		Casilla casilla = null;
		Connection con = null;
		try {
			con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement s = con
					.prepareStatement("select tipoCasilla from casillas where (nombre = ?)");
			s.setString(1, nombreCasilla);
			ResultSet rs = s.executeQuery();

			if (rs.next()) {
				String tipoCasilla = rs.getString("tipoCasilla");

				if (tipoCasilla.equals("normal"))
					casilla = new CasillaNormal(nombreCasilla);
				else if (tipoCasilla.equals("comodin"))
					casilla = new CasillaComodin(nombreCasilla,
							traerCasillasEnComodin(nombreCasilla));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (con != null)
				PoolConnection.getPoolConnection().realeaseConnection(con);
		}

		return casilla;
	}

	private ArrayList<Casilla> traerCasillasEnComodin(
			String nombreCasillaComodin) {
		ArrayList<Casilla> casillasEnComodin = new ArrayList<Casilla>();
		Connection con = null;
		try {
			con = PoolConnection.getPoolConnection().getConnection();
			PreparedStatement sCasillasEnComodin = con
					.prepareStatement("select casilla, cantidad from casillasEnComodin where casillaComodin = ?");

			sCasillasEnComodin.setString(1, nombreCasillaComodin);

			ResultSet rs = sCasillasEnComodin.executeQuery();

			while (rs.next()) {
				String nombreCasillaEnComodin = rs.getString("casilla");
				int cantidad = rs.getInt("cantidad");

				for (int i = 0; i < cantidad; i++) {
					Casilla casillaEnComodin = traer(nombreCasillaEnComodin);
					casillasEnComodin.add(casillaEnComodin);
				}
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (con != null)
				PoolConnection.getPoolConnection().realeaseConnection(con);
		}

		return casillasEnComodin;
	}
}
